package com.niiwoo.civet.mobile.controller.creditor;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.mobile.vo.request.creditor.*;
import com.niiwoo.civet.mobile.vo.request.creditor.CreditorSaleApplyRequestVO.CreditorSaleApplyDetailVO;
import com.niiwoo.civet.mobile.vo.response.creditor.*;
import com.niiwoo.civet.mobile.vo.response.user.UserBasicDataResponseVO;
import com.niiwoo.civet.trade.constant.TradeRedisKey;
import com.niiwoo.civet.trade.dto.request.creditor.CancelCreditorSaleRequestDTO;
import com.niiwoo.civet.trade.dto.request.creditor.CreditorSaleApplyRequestDTO;
import com.niiwoo.civet.trade.dto.request.creditor.CreditorSaleApplyRequestDTO.CreditorSaleApplyDetailDTO;
import com.niiwoo.civet.trade.dto.request.creditor.CreditorSaleOrderPageRequestDTO;
import com.niiwoo.civet.trade.dto.request.creditor.CreditorValidateRequestDTO;
import com.niiwoo.civet.trade.dto.response.creditor.*;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.enums.creditorSale.SaleDetailEndTypeEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.trade.service.creditor.CreditorRightsDubboService;
import com.niiwoo.civet.trade.service.creditor.CreditorSaleOrderDubboService;
import com.niiwoo.civet.user.constants.LoginAccountErrorCode;
import com.niiwoo.civet.user.dto.request.RefreshSMSCodeRequestDTO;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.enums.UserSMSTypeEnum;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserLoginAccountDubboService;
import com.niiwoo.civet.user.service.UserSMSDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.vo.Empty;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.shaded.com.google.common.collect.Maps;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/creditSaleOrder")
@Api(tags = "V5.3.0债转订单（出让）", description = "/creditSaleOrder")
@Slf4j
public class CreditorSaleOrderController {
	
	@Reference(version = "1.0.0")
    private CreditorSaleOrderDubboService creditorSaleOrderDubboService;
	
	@Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
	
	@Reference(version = "1.0.0")
	private UserSMSDubboService userSMSDubboService;
	
	@Reference(version = "1.0.0")
	private UserLoginAccountDubboService userLoginAccountDubboService;
	
	@Reference(version = "1.0.0")
	private TradeConfigDubboService tradeConfigDubboService;
	
	@Reference(version = "1.0.0")
	private CreditorRightsDubboService creditorRightsDubboService;
	
    @Autowired
    private PrivacyMasks privacyMasks;
    
    @Value("${creditorsale.h5-apply-url}")
    private String creditorSaleH5ApplyUrl;

    @Value("${creditorsale.h5-function-page-url}")
    private String creditorSaleFunctionPageUrl;

	@Value("${online_time_for_creditor}")
	private String onlineTime;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

	@PostMapping("/batch/list")
    @ApiOperation("（失效）V5.3.0债转订单列表(批次订单)——分页列表")
    public Result<UserCreditorSaleBatchOrderResponseVO> getUserAllCreditorBatchSaleOrderByPage(@RequestBody @Valid CreditorSaleOrderPageRequestVO request) {
		String userId = PrincipalContext.getUserId();
		
		CreditorSaleOrderPageRequestDTO requestDto = new CreditorSaleOrderPageRequestDTO();
		requestDto.setUserId(userId);
		requestDto.setPageNumber(request.getPageNumber());
		requestDto.setPageSize(request.getPageSize());
		
		PageCreditorSaleBatchOrderDTO pageRecords = creditorSaleOrderDubboService.getUserAllCreditorBatchSaleOrderByPage(requestDto);
		List<CreditorSaleBatchOrderDTO> list = pageRecords.getItems();
		UserCreditorSaleBatchOrderResponseVO resultVO = new UserCreditorSaleBatchOrderResponseVO();
		if (list != null && !list.isEmpty()) {
			List<CreditorSaleBatchOrderVO> creditorSaleBatchOrderVOs = new ArrayList<>();
        	
			List<CreditorSaleDetailOrderSimpleVO> details = null;
			CreditorSaleBatchOrderVO vo = null;
        	for (CreditorSaleBatchOrderDTO dto : list) {
        		vo = new CreditorSaleBatchOrderVO();
        		
        		BeanUtils.copyProperties(dto, vo);
        		
        		vo.setCreateTime(dto.getCreateTime().getTime());
        		
        		if (dto.getDetails() != null && !dto.getDetails().isEmpty()) {
    				details = new ArrayList<>();
    				
    				CreditorSaleDetailOrderSimpleVO simpleVO = null;
    				for (CreditorSaleDetailOrderSimpleDTO detailDto : dto.getDetails()) {
    					simpleVO = new CreditorSaleDetailOrderSimpleVO();
    					
    					BeanUtils.copyProperties(detailDto, simpleVO);
    					
    					details.add(simpleVO);
    				}
    				
    				vo.setDetails(details);
    			}
        		
        		creditorSaleBatchOrderVOs.add(vo);
        	}
        	resultVO.setItems(creditorSaleBatchOrderVOs);
		}
		
		resultVO.setTotalCount(pageRecords.getTotalCount());
        resultVO.setTotalPage(pageRecords.getTotalPage());

        return Result.with(resultVO);
    }

	@PostMapping("/detail/list")
    @ApiOperation("V5.3.0债转订单列表(明细订单)——分页列表")
    public Result<UserCreditorSaleDetailOrderResponseVO> getUserAllDetailCreditorSaleOrderByPage(@RequestBody @Valid CreditorSaleOrderPageRequestVO request) {
		String userId = PrincipalContext.getUserId();

		CreditorSaleOrderPageRequestDTO requestDto = new CreditorSaleOrderPageRequestDTO();
		requestDto.setUserId(userId);
		requestDto.setPageNumber(request.getPageNumber());
		requestDto.setPageSize(request.getPageSize());

		PageCreditorSaleDetailOrderDTO pageRecords = creditorSaleOrderDubboService.getUserAllCreditorDetailSaleOrderByPage(requestDto);
		List<CreditorSaleDetailOrderDTO> list = pageRecords.getItems();
		UserCreditorSaleDetailOrderResponseVO resultVO = new UserCreditorSaleDetailOrderResponseVO();
		if (list != null && !list.isEmpty()) {

			List<CreditorSaleDetailOrderSimpleVO> detailVOs = new ArrayList<>();
			CreditorSaleDetailOrderSimpleVO vo = null;
        	for (CreditorSaleDetailOrderDTO dto : list) {
        		vo = new CreditorSaleDetailOrderSimpleVO();

        		BeanUtils.copyProperties(dto, vo);

        		vo.setCreateTime(dto.getCreateTime().getTime());

        		detailVOs.add(vo);
        	}
        	resultVO.setItems(detailVOs);
		}

		resultVO.setTotalCount(pageRecords.getTotalCount());
        resultVO.setTotalPage(pageRecords.getTotalPage());
		
        return Result.with(resultVO);
    }
	
	@PostMapping("/batch")
    @ApiOperation("V5.3.0债转批次订单信息")
    public Result<CreditorSaleBatchOrderResponseVO> getCreditorSaleBatchOrder(@RequestBody @Valid CreditorSaleBatchOrderRequestVO request) {
		String userId = PrincipalContext.getUserId();
		
		CreditorSaleBatchOrderDTO dto = creditorSaleOrderDubboService.getCreditorSaleBatchOrder(userId, request.getCreditorSaleBatchId());
		
		CreditorSaleBatchOrderResponseVO resultVO = new CreditorSaleBatchOrderResponseVO();

		if (dto != null) {
			BeanUtils.copyProperties(dto, resultVO);
			
			if (dto.getDetails() != null && !dto.getDetails().isEmpty()) {
				List<CreditorSaleDetailOrderSimpleVO> details = new ArrayList<>();
				
				CreditorSaleDetailOrderSimpleVO simpleVO = null;
				for (CreditorSaleDetailOrderSimpleDTO detailDto : dto.getDetails()) {
					simpleVO = new CreditorSaleDetailOrderSimpleVO();
					
					BeanUtils.copyProperties(detailDto, simpleVO);
					
					details.add(simpleVO);
				}
				
				resultVO.setDetails(details);
			}
		}
		
        return Result.with(resultVO);
    }
	
	@PostMapping("/detail")
    @ApiOperation("V5.3.0债转明细订单信息")
    public Result<CreditorSaleDetailOrderResponseVO> getCreditorSaleDetailOrder(@RequestBody @Valid CreditorSaleDetailOrderRequestVO request) {
		String userId = PrincipalContext.getUserId();
		
		CreditorSaleDetailOrderDTO dto = creditorSaleOrderDubboService.getCreditorSaleDetailOrder(userId, request.getCreditorSaleDetailId());
		
		CreditorSaleDetailOrderResponseVO resultVO = new CreditorSaleDetailOrderResponseVO();
		
		if (dto != null) {
			BeanUtils.copyProperties(dto, resultVO);

			UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(dto.getUserId());
	        if(userBasicInfoResponseDTO != null){
	        	UserBasicDataResponseVO userBasicDataResponseVO = new UserBasicDataResponseVO();
	            userBasicDataResponseVO.setUserId(userBasicInfoResponseDTO.getUserId());
	            userBasicDataResponseVO.setNickName(userBasicInfoResponseDTO.getNickName());
	            userBasicDataResponseVO.setNiiwooCode(userBasicInfoResponseDTO.getNiiwooCode());
	            userBasicDataResponseVO.setNiiwooScore(userBasicInfoResponseDTO.getNiiwooScore());
	            userBasicDataResponseVO.setHeadImage(userBasicInfoResponseDTO.getHeadImage());

	            resultVO.setUser(userBasicDataResponseVO);
	        }
		}
		
        return Result.with(resultVO);
    }

	@PostMapping("/validateCreditorSale")
	@ApiOperation("校验是否可以出让债权（贾波）")
	public Result<CreditorValidateRespnseVO> validateCreditorSale(@RequestBody @Valid CreditorValidateRequestVO request) {
		String userId = PrincipalContext.getUserId();
		
		CreditorValidateRequestDTO creditorValidateRequestDTO = new CreditorValidateRequestDTO();
		creditorValidateRequestDTO.setUserId(userId);
		creditorValidateRequestDTO.setInvestOrderId(request.getInvestOrderId());
		creditorSaleOrderDubboService.validateSaleCreditor(creditorValidateRequestDTO);
		
		CreditorValidateRespnseVO responseVO = new CreditorValidateRespnseVO();
		responseVO.setForwardUrl(creditorSaleH5ApplyUrl + request.getInvestOrderId());

		responseVO.setIsFirstClick((byte) 1);

		DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
		Date currentDate = new Date();
		try {
			date = format.parse(onlineTime);
		} catch (ParseException e) {
			log.info("IsShowFunctionPage时间转换异常");
			return Result.with(responseVO);
		}
		if (currentDate.before(new DateTime(date).plusMonths(1).toDate())) {
			// 校验通过后新功能介绍逻辑处理
			String userIsFirstClickKey = TradeRedisKey.FUNCTION_PAGE_IS_SHOW;
			if (!redisTemplate.opsForSet().isMember(userIsFirstClickKey, userId)) {
				TradableInvestOrderStatDTO creditorSaleOrderRateAreaDTO = creditorRightsDubboService.getCreditorSaleOrderRateArea();
				responseVO.setIsFirstClick((byte) 0);
				responseVO.setMinFeeRate(creditorSaleOrderRateAreaDTO.getMinFeeRate());
				responseVO.setNewFunctionPageUrl(creditorSaleFunctionPageUrl + "?id=" + request.getInvestOrderId());
			}
		}
		return Result.with(responseVO);
	}
	
	@PostMapping("/creditorSaleApply")
	@ApiOperation("债权出让申请（贾波）")
	public Result<CreditorSaleApplyRespnseVO> creditorSaleApply(@RequestBody @Valid CreditorSaleApplyRequestVO requestVO) {
		CreditorSaleApplyRequestDTO creditorSaleApplyRequestDTO = new CreditorSaleApplyRequestDTO();
		
		List<CreditorSaleApplyDetailDTO> creditorSaleApplyDetailDTOList = new ArrayList<>();
		creditorSaleApplyRequestDTO.setUserId(PrincipalContext.getUserId());
		creditorSaleApplyRequestDTO.setTotalSaleAmount(requestVO.getTotalSaleAmount());
		creditorSaleApplyRequestDTO.setCreditorSaleApplyDetailDTOList(creditorSaleApplyDetailDTOList);
		
		List<CreditorSaleApplyDetailVO> applyDetailVOList = requestVO.getCreditorSaleApplyDetailVOList();
		if (applyDetailVOList.size() > 1) {
			creditorSaleApplyRequestDTO.setIsBatch((byte) 1);
		} else {
			creditorSaleApplyRequestDTO.setIsBatch(requestVO.getIsBatch() != null ? requestVO.getIsBatch() : 0);
		}
		applyDetailVOList.forEach(applyDetailVO -> {
			CreditorSaleApplyRequestDTO.CreditorSaleApplyDetailDTO applyDetailDTO = new CreditorSaleApplyRequestDTO.CreditorSaleApplyDetailDTO();
			applyDetailDTO.setInvestOrderId(applyDetailVO.getInvestOrderId());
			applyDetailDTO.setSaleAmount(applyDetailVO.getAmount());
			applyDetailDTO.setOffPercent(applyDetailVO.getOffPercent());
			applyDetailDTO.setExpenseRate(applyDetailVO.getExpenseRate());
			creditorSaleApplyDetailDTOList.add(applyDetailDTO);
		});
		CreditorSaleApplyResponseDTO responseDTO = creditorSaleOrderDubboService.creditorSaleApply(creditorSaleApplyRequestDTO);

		CreditorSaleApplyRespnseVO responseVO = new CreditorSaleApplyRespnseVO();
		responseVO.setTotalSaleAmount(responseDTO.getTotalSaleAmount());
		responseVO.setCreditorSaleDetailIdList(responseDTO.getCreditorSaleDetailIdList());
		
		// 扩展属性
		try {
			Map<String, String> extendAttribute = Maps.newHashMap();
			String debtTransferTimeLimit = tradeConfigDubboService.selectTradeConfigByEmun(TradeConfigEnum.DEBT_TRANSFER_TIME_LIMIT);
			extendAttribute.put("debtTransferTimeLimit", StringUtils.hasLength(debtTransferTimeLimit) ? debtTransferTimeLimit : "24");
			responseVO.setExtendAttribute(extendAttribute);
		} catch (Exception e) {
			log.error("债权出让申请获取页面需要的扩展属性字段异常", e);
		}
		
		return Result.with(responseVO);
	}
	
	@PostMapping("/preCreditorSaleApply")
	@ApiOperation("债权出让申请预处理（贾波）")
	public Empty preCreditorSaleApply(@RequestBody @Valid CreditorSaleApplyRequestVO requestVO) {
		CreditorSaleApplyRequestDTO creditorSaleApplyRequestDTO = new CreditorSaleApplyRequestDTO();
		
		List<CreditorSaleApplyDetailDTO> creditorSaleApplyDetailDTOList = new ArrayList<>();
		creditorSaleApplyRequestDTO.setUserId(PrincipalContext.getUserId());
		creditorSaleApplyRequestDTO.setTotalSaleAmount(requestVO.getTotalSaleAmount());
		creditorSaleApplyRequestDTO.setCreditorSaleApplyDetailDTOList(creditorSaleApplyDetailDTOList);

		List<CreditorSaleApplyDetailVO> applyDetailVOList = requestVO.getCreditorSaleApplyDetailVOList();
		applyDetailVOList.forEach(applyDetailVO -> {
			CreditorSaleApplyRequestDTO.CreditorSaleApplyDetailDTO applyDetailDTO = new CreditorSaleApplyRequestDTO.CreditorSaleApplyDetailDTO();
			applyDetailDTO.setInvestOrderId(applyDetailVO.getInvestOrderId());
			applyDetailDTO.setSaleAmount(applyDetailVO.getAmount());
			applyDetailDTO.setOffPercent(applyDetailVO.getOffPercent());
			applyDetailDTO.setExpenseRate(applyDetailVO.getExpenseRate());
			creditorSaleApplyDetailDTOList.add(applyDetailDTO);
		});
		creditorSaleOrderDubboService.preCreditorSaleApply(creditorSaleApplyRequestDTO);
		return Empty.getInstance();
	}

    @PostMapping("/cancelCreditorSale")
    @ApiOperation("取消债权出让（贾波）")
    public Empty cancelCreditorSale(@RequestBody @Valid CancelCreditorSaleRequestVO request) {
		CancelCreditorSaleRequestDTO cancelCreditorSaleRequestDTO = new CancelCreditorSaleRequestDTO();
		cancelCreditorSaleRequestDTO.setUserId(PrincipalContext.getUserId());
		cancelCreditorSaleRequestDTO.setCreditorSaleDetailIdList(request.getCreditorSaleDetailIdList());
		cancelCreditorSaleRequestDTO.setEndTypeEnum(SaleDetailEndTypeEnum.USER_OPERATION);
    	creditorSaleOrderDubboService.cancelCreditorSale(cancelCreditorSaleRequestDTO);
    	
        return Empty.getInstance();
    }
    
    @RequestMapping(path = "/getVerificationCode", method = RequestMethod.POST)
    @ApiOperation(value = "发送注册短信验证码（贾波）")
	public Result<VerificationCodeRespnseVO> getVerificationCode() {
    	UserBasicInfoResponseDTO userBasicInfo = userBasicInfoDubboService.getUserBasicInfo(PrincipalContext.getUserId());
		RefreshSMSCodeRequestDTO refreshSMSCodeRequestDTO = new RefreshSMSCodeRequestDTO();
		refreshSMSCodeRequestDTO.setSmsType(UserSMSTypeEnum.CREDITOR_RIGHTS_TRANSFER);
		refreshSMSCodeRequestDTO.setLoginMobileNo(userBasicInfo.getMobileNo());
		if (!userSMSDubboService.createSMS(refreshSMSCodeRequestDTO)) {
			throw new BizException(LoginAccountErrorCode.SMS_SEND_FAIL);
		}
		
		VerificationCodeRespnseVO respnseVO = new VerificationCodeRespnseVO();
		respnseVO.setMobileNo(privacyMasks.maskMobile(userBasicInfo.getMobileNo()));
        return Result.with(respnseVO);
    }

	@RequestMapping(path = "/checkVerificationCode", method = RequestMethod.POST)
	@ApiOperation(value = "验证注册短信验证码（贾波）")
	public Result<CheckVerificationCodeRespnseVO> checkVerificationCode(@RequestBody @Valid CheckVerificationCodeRequestVO requestVO) {
		UserBasicInfoResponseDTO userBasicInfo = userBasicInfoDubboService.getUserBasicInfo(PrincipalContext.getUserId());
		CheckVerificationCodeRespnseVO responseVO = new CheckVerificationCodeRespnseVO();
		String result = userLoginAccountDubboService.validRegisterSMSCode(userBasicInfo.getMobileNo(), requestVO.getMsgCode(), UserSMSTypeEnum.CREDITOR_RIGHTS_TRANSFER);
		responseVO.setResult(result);
		return Result.with(responseVO);
	}
}
